package com.siwei.mes.service.system.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.siwei.mes.common.base.BaseParams;
import com.siwei.mes.common.query.PageQuery;
import com.siwei.mes.common.util.DateHelper;
import com.siwei.mes.common.util.JsonUtils;
import com.siwei.mes.common.util.MacTools;
import com.siwei.mes.config.UidUtils;
import com.siwei.mes.entity.dto.EquipmentTestProjectInfo;
import com.siwei.mes.entity.system.Equipment;
import com.siwei.mes.entity.system.EquipmentCycle;
import com.siwei.mes.entity.system.ExcelEquipmentDataObject;
import com.siwei.mes.enums.GenerateCodeEnum;
import com.siwei.mes.enums.RoleEnum;
import com.siwei.mes.enums.VerificationCycleEnum;
import com.siwei.mes.mapper.system.EquipmentMapper;
import com.siwei.mes.service.experiment.ExperimentService;
import com.siwei.mes.service.system.AuthService;
import com.siwei.mes.service.system.EquipmentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;

import static com.siwei.mes.common.exception.handler.MessageHandler.assertTrue;

/**
 * 设备表(Equipment)表服务实现类
 *
 * @author linzi
 * @since 2023-11-25 22:22:21
 */
@Slf4j
@Service
public class EquipmentServiceImpl implements EquipmentService {
    @Value(value = "${excel.mac}")
    private String ADDRESS_MAC;
    @Value(value = "${excel.windows}")
    private String ADDRESS_WINDOWS;
    @Value(value = "${excel.linux}")
    private String ADDRESS_LINUX;
    @Resource
    private EquipmentMapper equipmentMapper;
    @Resource
    private AuthService authService;
    @Resource
    private ExperimentService experimentService;

    /**
     * 判断是否有权限
     */
    public void checkRole() {
        List<String> roleList = new ArrayList<>();
        roleList.add(RoleEnum.EXTERNAL_INSPECTOR.getCode());
        roleList.add(RoleEnum.TEAM_LEADER.getCode());

        String loginUserRole = authService.getLoginUserRole();

        if (roleList.contains(loginUserRole)) {
            assertTrue("您暂无权限操作");
        }
    }

    @Override
    public Long create(Equipment entity) {
        this.checkRole();
        entity.init(true);
        if (StringUtils.isBlank(entity.getEquipmentNo())) {
            // 如果设备编号为空 自动生成一个
            entity.setEquipmentNo(UidUtils.genNo(GenerateCodeEnum.EQUIPMENT.getCode()));
        }
        equipmentMapper.insertSelective(entity);
        /**修改对应试验委托的仪器设备*/
        experimentService.updateEquipmentInfo();
        return entity.getId();
    }

    @Override
    public void update(Equipment entity) {
        this.checkRole();
        Equipment equipment = equipmentMapper.selectByPrimaryKey(entity.getId());
        assertTrue(equipment == null, "设备表信息不存在");
        entity.init(false);
        equipmentMapper.updateByPrimaryKeySelective(entity);
        /**修改对应试验委托的仪器设备*/
        experimentService.updateEquipmentInfo();
    }

    @Override
    public void updateList(EquipmentCycle entity) {
        this.checkRole();
        assertTrue(entity.getIds() == null || entity.getIds().isEmpty(), "设备id不允许为空！");
        assertTrue(entity.getVerificationCycle() == null && entity.getWarningCycle() == null, "检定周期与预警设置不允许为全部为空！");

        for (String equipment : entity.getIds()) {

            Equipment eq = new Equipment().setId(Long.parseLong(equipment)).setWarningCycle(entity.getWarningCycle()).setVerificationCycle(entity.getVerificationCycle());
            eq.init(false);

            equipmentMapper.updateVerificationCycle(eq);
        }
    }

    @Override
    public void delete(Long id) {
        this.checkRole();
        Equipment equipment = equipmentMapper.selectByPrimaryKey(id);
        assertTrue(equipment == null, "设备表信息不存在");
        equipmentMapper.deleteByPrimaryKey(id);

        experimentService.updateEquipmentInfo();
    }

    @Override
    public PageInfo<Equipment> getPage(PageQuery<Equipment, Equipment> query) {
        Equipment searchParam = query.getParams();

        PageInfo<Equipment> objectPageInfo = PageHelper.startPage(query.getPageNum(), query.getPageSize())
                .doSelectPageInfo(() -> equipmentMapper.getList(searchParam));

        for (Equipment equipment : objectPageInfo.getList()) {
            this.payloadOtherInfo(equipment);
        }
        return objectPageInfo;
    }

    @Override
    public Equipment loadById(Long id) {
        Equipment equipment = equipmentMapper.selectByPrimaryKey(id);
        if (equipment != null) {
            this.payloadOtherInfo(equipment);
        }
        return equipment;
    }

    @Override
    public List<Equipment> getAll(Equipment entity) {
        List<Equipment> list = equipmentMapper.getList(entity);
        for (Equipment equipment : list) {
            this.payloadOtherInfo(equipment);
        }
        return list;
    }

    private void payloadOtherInfo(Equipment equipment) {
        /**下次检定时间*/
        if (equipment.getVerificationCycle() != null && equipment.getLastDetectionTime() != null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(equipment.getLastDetectionTime());
            // 要增加的月数
            int monthsToAdd = equipment.getVerificationCycle();
            calendar.add(Calendar.MONTH, monthsToAdd);
            Date newDate = calendar.getTime();
            equipment.setNextTestingTime(newDate);
        }
        /**拼接试验项目名称*/
        JSONArray testProjectJson = equipment.getTestProjectJson();
        if (!testProjectJson.isEmpty()) {
            StringBuilder testProjectNameStr = new StringBuilder();
            for (Object o : testProjectJson) {
                JSONObject jsonObject = (JSONObject) o;
                testProjectNameStr.append(jsonObject.get("name")).append(",");
            }
            if (testProjectNameStr.length() > 0) {
                equipment.setTestProjectNameStr(testProjectNameStr.deleteCharAt(testProjectNameStr.length() - 1).toString());
            }
        }
    }

    @Override
    public List<Equipment> getEquipmentInfo(String testProjectType) {
        List<Equipment> list = new ArrayList<>();
        List<Equipment> equipmentList = equipmentMapper.getEquipmentInfo(testProjectType);
        /**这里还要过滤一下 因为是模糊查询的 所有会不对*/
        for (Equipment equipment : equipmentList) {
            JSONArray testProjectJson = equipment.getTestProjectJson();
            for (Object o : testProjectJson) {
                JSONObject jsonObject = (JSONObject) o;
                if (jsonObject.get("no").equals(testProjectType)) {
                    list.add(equipment);
                }
            }
        }
        return list;
    }

    @Override
    public Map<String, String> getAllMaterialsTypeEquipmentInfo() {
        Map<String, String> map = new HashMap<>();
        List<Equipment> list = equipmentMapper.getList(new Equipment());
        for (Equipment equipment : list) {
            JSONArray testProjectJson = equipment.getTestProjectJson();
            if (testProjectJson.isEmpty()) {
                continue;
            }
            List<EquipmentTestProjectInfo> testProjectInfoList = JsonUtils.jsonToList(testProjectJson, EquipmentTestProjectInfo.class);
            if (testProjectInfoList.isEmpty()) {
                continue;
            }

            for (EquipmentTestProjectInfo testProjectInfo : testProjectInfoList) {
                String str = map.get(testProjectInfo.getNo());
                if (StringUtils.isBlank(str)) {
                    map.put(testProjectInfo.getNo(), equipment.getEquipmentName());
                } else {
                    map.put(testProjectInfo.getNo(), str + "," + equipment.getEquipmentName());
                }
            }
        }
        return map;
    }

    @Override
    public void importEquipment(String filePath) {

        ImportParams params = new ImportParams();
        params.setTitleRows(0); // 设置标题行，
        params.setHeadRows(1); // 设置表头行，

        try {
            //读取excel 文件 转换至实体
            List<ExcelEquipmentDataObject> dataList = ExcelImportUtil.importExcel(new File(filePath), ExcelEquipmentDataObject.class, params);

            for (ExcelEquipmentDataObject dataObject : dataList) {
                Equipment equipment = new Equipment();
                equipment.init(true);
                BeanUtils.copyProperties(dataObject, equipment);
                if (StringUtils.isNotBlank(dataObject.getBuyTime())) {
                    String[] buyTime = dataObject.getBuyTime().split("\\.");
                    if (buyTime.length == 2) {
                        equipment.setBuyTime(DateHelper.getDateByYearMonthDay(buyTime[0], buyTime[1]));
                    }
                }
                if (StringUtils.isNotBlank(dataObject.getFactoryTime())) {
                    equipment.setFactoryTime(DateHelper.isLegalDateSlash(dataObject.getFactoryTime()));
                }
                equipment.setSaveAddress(dataObject.getPlacementLocation());
                equipment.setCustodyUserName("李威");
                /**预警天数默认为7天**/
                equipment.setWarningCycle(7);
                equipment.setVerificationCycle(VerificationCycleEnum.selectByCodeName(dataObject.getVerificationCycle()));
                equipmentMapper.insert(equipment);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("读取excel文件失败：" + e.getMessage(), e);
        }

    }

    /**
     * 根据服务类型获取磁盘路径
     * 默认是windows磁盘路径
     *
     * @return
     */
    public String getPathName() {
        String operSystem = MacTools.getOperSystem();
        if (Arrays.stream(BaseParams.MAC_LIST).parallel().anyMatch(operSystem::contains)) {
            return ADDRESS_MAC;
        } else if (Arrays.stream(BaseParams.LINUX_LIST).parallel().anyMatch(operSystem::contains)) {
            return ADDRESS_LINUX;
        }
        return ADDRESS_WINDOWS;
    }

    public static void main(String[] args) {
        //String str = "[{\"no\": \"FINE_AGGREGATE\", \"name\": \"细骨料\"}, {\"no\": \"CONCRETE\", \"name\": \"混凝土\"}, {\"no\": \"CONCRETE_ADMIXTURE\", \"name\": \"混凝土外加剂\"}]";
        String str = "[]";
        JSONArray jsonArray = JSONArray.parseArray(str);

        List<EquipmentTestProjectInfo> testProjectInfoList = JsonUtils.jsonToList(jsonArray, EquipmentTestProjectInfo.class);
        System.out.println(testProjectInfoList);
    }
}
